home *** CD-ROM | disk | FTP | other *** search
- #include "choicebx.h"
- #include "formline.h"
-
- #include <dos.h>
-
- #define MAX_STRING 3000
-
- ChoiceBox::ChoiceBox(rect coordinates, char* fName, char* h,
- char* HOT, int POS, int START,
- loc ITEMSIZE, char** ITEMSTRINGS,
- int* ITEMLIST,
- loc ITEMDISTANCE,
- rect STATUSPOS,
- int STATUSTYPE, char** STATUSSTRINGS,
- int* STATUSLIST,
- int res, int s, BORDERS b_type, BORDERS hdr_b_type,
- int pat, int hdr_pat)
- : Window(coordinates, fName, h, s, b_type, hdr_b_type, res,
- pat, hdr_pat)
- {
- item = new Item();
- hot = HOT; pos = POS; start = START; itemSize = ITEMSIZE;
- itemList = ITEMLIST; itemStrings = ITEMSTRINGS;
- itemDistance = ITEMDISTANCE; statusPos = STATUSPOS;
- statusType = STATUSTYPE; statusStrings = STATUSSTRINGS;
- statusList = STATUSLIST;
- calcConsts();
- }
- ////////////////////////
- void ChoiceBox::calcConsts()
- {
- calcItemsNumber();
- rect r = user_screen();
- raw = (r.height() - itemDistance.Y)
- / (screenYT(itemSize.Y) + itemDistance.Y);
- if(raw == 0)
- raw = r.height() / screenYT(itemSize.Y);
-
- column = (r.width() - itemDistance.X)
- / (screenXL(itemSize.X) + itemDistance.X);
-
- if(column > count) // if not enough items for filling the box
- column = count;
-
- if((raw == 1 && screenYT(itemSize.Y) > r.height())
- || (screenXL(itemSize.X) + 2 * itemDistance.X > r.width())
- || (raw != 1 && screenYT(itemSize.Y) + 2 * itemDistance.Y > r.height()))
- {
- available = 0;
- return;
- }
- available = 1;
- }
- ////////////////////////////
- void ChoiceBox::hide()
- {
- if(once && *fileName != '\0')
- item->hide(getItemCoord());
- Window::hide();
- }
- ///////////////////////////
- void ChoiceBox::moveTo(int number)
- {
- if(number == 0)
- return;
- item->hide(getItemCoord());
- if(number < start || number > start + raw * column - 1)
- {
- start = pos = number;
- show();
- return;
- }
- pos = number;
- item->show(getItemCoord());
- showStatus(number, pattern);
- }
- ////////////////////////////
- void ChoiceBox::endOfList()
- {
- if(pos == count)
- {
- pos = 1;
- start = 1;
- }
- else
- {
- pos = count;
- if(count <= raw * column)
- start = 0;
- else
- start = count - raw * column + 1;
- }
- }
- //////////////////////////
- void ChoiceBox::home()
- {
- item->hide(getItemCoord());
- pos = start;
- moveTo(pos);
- }
- ////////////////////////
- void ChoiceBox::end()
- {
- item->hide(getItemCoord());
- if(column * raw - pos + start > count - pos)
- pos = count;
- else
- pos = start + column * raw - 1;
- moveTo(pos);
- }
- ////////////////////////
- void ChoiceBox::pgUp()
- {
- item->hide(getItemCoord());
- if(pos >= raw * column)
- pos -= raw * column;
- else
- pos = 1;
- moveTo(pos);
- }
- ////////////////////////
- void ChoiceBox::pgDn()
- {
- item->hide(getItemCoord());
- if(count >= pos + column * raw)
- pos += column * raw;
- else
- pos = count;
- moveTo(pos);
- }
- ////////////////////////
- void ChoiceBox::left()
- {
- item->hide(getItemCoord());
- if(pos > 1)
- pos--;
- else
- pos = count;
- moveTo(pos);
- }
- ////////////////////////
- void ChoiceBox::right()
- {
- item->hide(getItemCoord());
- if(count >= pos + 1)
- pos++;
- else
- pos = 1;
- moveTo(pos);
- }
- ////////////////////////
- void ChoiceBox::up()
- {
- item->hide(getItemCoord());
- if(pos > column)
- pos -= column;
- else
- pos = count;
- moveTo(pos);
- }
- ////////////////////////
- void ChoiceBox::dn()
- {
- item->hide(getItemCoord());
- if(count >= pos + column)
- pos += column;
- else
- pos = 1;
- moveTo(pos);
- }
- ////////////////////////
- void ChoiceBox::toTop()
- {
- item->hide(getItemCoord());
- pos = 1;
- moveTo(pos);
- }
- /////////////////////////
- void ChoiceBox::toBottom()
- {
- item->hide(getItemCoord());
- pos = count;
- moveTo(pos);
- }
- /////////////////////////
- int ChoiceBox::mouseOn(event e)
- {
- rect r = user_screen();
- loc wh = e.where();
- int mouse_raw = (wh.Y - r.origin.Y
- - itemDistance.Y)
- / (screenYT(itemSize.Y) + itemDistance.Y);
- int mouse_col = (wh.X - r.origin.X
- - itemDistance.X)
- / (screenXL(itemSize.X) + itemDistance.X);
- int result;
- result = mouse_raw * column + mouse_col + 1;
- return (result > count || result < 0) ? 0 : result;
- }
- /////////////////////////
- rect ChoiceBox::getItemCoord()
- {
- rect rec = user_screen();
- int position = pos - start;
- int r = position / column; // first raw is 0
- int c = position - r * column; // first column is 0
- int left = c * (screenXL(itemSize.X) + itemDistance.X)
- + itemDistance.X;
- int right = left + screenXR(itemSize.X) + 2; // + itemDistance.X);
- int top = r * (screenYT(itemSize.Y) + itemDistance.Y)
- + itemDistance.Y;
- int bottom = top + screenYB(itemSize.Y) + 2; // + itemDistance.Y);
- return rect(rec.origin.X + left, rec.origin.Y + top,
- rec.origin.X + right, rec.origin.Y + bottom);
- }
- //////////////////////////
- void ChoiceBox::show()
- {
- Window::show();
- // Window::clrscr();
- if(!available || (itemStrings == NULL && itemList == NULL))
- return;
- int p = pos;
- for(int i = 1; i <= raw; i++)
- {
- for(int j = 1; j <= column; j++)
- {
- pos = start + (i - 1) * column + j - 1;
- showItem();
- if(pos == count)
- break;
- }
- if(pos == count)
- break;
- }
- pos = p;
- moveTo(pos);
- }
- ///////////////////////////
- void ChoiceBox::repose(rect new_coord)
- {
- Window::repose(new_coord);
- calcConsts();
- }
- ///////////////////////////
- void ChoiceBox::exe(int act)
- {
- e.what = act ? KEYEVENT : NOEVENT;
-
- switch(act)
- {
- case AC_LEFT: e.key = EVENT_LEFT; break;
- case AC_RIGHT: e.key = EVENT_RIGHT; break;
- case AC_UP: e.key = EVENT_UP; break;
- case AC_DOWN: e.key = EVENT_DN; break;
- case AC_PG_UP: e.key = EVENT_PG_UP; break;
- case AC_PG_DN: e.key = EVENT_PG_DN; break;
- case AC_CTRL_PG_UP: e.key = EVENT_CTRL_PG_UP; break;
- case AC_CTRL_PG_DN: e.key = EVENT_CTRL_PG_DN; break;
- case AC_CANCEL: e.key = (isRet(RET_REMOVE))
- ? EVENT_ALT_F3 : EVENT_ESC;
- break;
- case AC_OK: e.key = EVENT_F2; break;
- }
- int res = pos; // reserv, used if we input ESC - like command
- rect r = textRect(user_screen());
- mouseHideCursor();
- if(!act)
- hilite();
-
- int on = 0;
- mouseShowCursor();
- while(1)
- {
- mouseShowCursor();
- if(!act && !(e.what == MOUSEEVENT && !on))
- get_event();
- else
- on = 1;
- mouseHideCursor();
- if(statusType) // status line
- showStatus(pos, pattern);
-
- char* ch = 0; // hot keys
- if(hot != NULL
- && (ch = strchr(strlwr(hot), e.keypress())) && (e.key < 256 )
- && e.keypress())
- {
- moveTo(ch - hot + 1);
- e.what = KEYEVENT;
- e.key = EVENT_RETURN;
- }
-
- if(e.what == KEYEVENT)
- switch(e.key)
- {
- case EVENT_F1: global_i[0] = action_type; return;
- case EVENT_RIGHT: if(available) right(); break;
- case EVENT_LEFT: if(available) left(); break;
- case EVENT_UP: if(available) up(); break;
- case EVENT_DN: if(available) dn(); break;
- case EVENT_HOME: if(available) home(); break;
- case EVENT_PG_UP: if(available) pgUp(); break;
- case EVENT_END: if(available) end(); break;
- case EVENT_PG_DN: if(available) pgDn(); break;
- case EVENT_CTRL_PG_UP: if(available) toTop(); break;
- case EVENT_CTRL_PG_DN: if(available) toBottom(); break;
- case EVENT_ESC: if(available) moveTo(res); global_num = 0;
- global_i[0] = AC_NULL; return;
- case EVENT_F6:
- case EVENT_F10:
- case EVENT_TAB:
- case EVENT_ALT_F3:
- case EVENT_ALT_F4:
- case EVENT_ALT_TAB:
- unhilite(); global_num = pos;
- global_i[0] = 0; return;
- case EVENT_F2:
- case EVENT_RETURN : unhilite(); global_num = pos;
- global_i[0] = action_type; return;
- }
- else
- {
- if(!mouse_in(e.where()))
- {
- unhilite();
- global_num = 0; global_i[0] = AC_NULL;
- return;
- } // outside of menu box
- int new_pos;
-
- if((new_pos = start + mouseOn(e) - 1) && available) // mouse pressed at the item
- {
- item->hide(getItemCoord());
- unhilite();
- e.what = KEYEVENT;
- e.key = EVENT_RETURN;
- global_num = new_pos;
- moveTo(new_pos);
- global_i[0] = action_type;
- return;
- }
- }
- if(act) // leave menu and return to the object which calls it
- { // after single processing of "act" command
- global_num = pos;
- return;
- }
- }
- }
- //////////////////////////
-
-